<?php
/**
 * 
 *
 * LICENSE
 *
 * @category   Win
 * @package    Win_Db_Table
 * @subpackage Table
 * @copyright  Copyright (c) 2005-2008 Win
 * @license    
 */

require_once 'Zend/Db/Table/Abstract.php';
require_once 'Win/Db/Exception.php';
require_once 'Zend/Loader.php';

abstract class My_Db_Table extends Zend_Db_Table_Abstract
{
    
    const REF_TABLE = 'refTable';
    const REF_SHOWS = 'refShows';
    
    //protected $_rowClass = 'Win_Db_Row';
    
    //protected $_rowsetClass = 'Win_Db_Rowset';
    
    protected $_comments = array();
    
    protected $_uniques = array();
        
    public function __construct(){
    	if ($dbprefix = Zend_Registry::get('dbprefix')){ 
        	$this->_name = $dbprefix . '_' . $this->_name;
    	} 
        parent::__construct();
    }
    
    public function init()
    {
        parent::init();        
    }
      
    /*  
    protected function _setupMetadata()
    {
    	if ($this->metadataCacheInClass() && (count($this->_metadata) > 0)) {
            return true;
        }
        
        $isMetadataFromCache = true;

        if (null === $this->_metadataCache && null !== self::$_defaultMetadataCache) {
            $this->_setMetadataCache(self::$_defaultMetadataCache);
        }

        if (null !== $this->_metadataCache) {
            $cacheId = md5("$this->_schema.$this->_name");
        }

        if (null === $this->_metadataCache || !($metadata = json_decode(($this->_metadataCache->load($cacheId)),true))) {
            $isMetadataFromCache = false;
            $metadata = $this->_db->describeTable($this->_name, $this->_schema);
            $cols = array_keys($metadata);
            $comments = $this->_showFullFields($cols);
            $uniques = $this->_showIndex($cols);
            foreach ($cols as $col){
                $metadata[$col]['COMMENT'] = $comments[$col];
                $metadata[$col]['UNIQUE'] = $uniques[$col];
            }

            if (null !== $this->_metadataCache && !$this->_metadataCache->save(json_encode($metadata), $cacheId)) {
                require_once 'Zend/Db/Table/Exception.php';
                throw new Zend_Db_Table_Exception('Failed saving metadata to metadataCache');
            }
        }
        
        $this->_metadata = $metadata;
        $this->_cols = array_keys($this->_metadata);
        foreach ($this->_cols as $col){
            $this->_comments[$col] = $metadata[$col]['COMMENT'];
            if (!empty($metadata[$col]['UNIQUE'])){
                $this->_uniques[$metadata[$col]['UNIQUE']][] = $col;
            }  
        }
        return $isMetadataFromCache;
    }    
    */
    
    protected function _getUniques()
    {
    	if (empty($this->_uniques) && $this->_db instanceof Zend_Db_Adapter_Pdo_Mysql){
	    	$cols = $this->_getCols();
	        $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
	        $this->_uniques = array();
	        
            $sql = 'SHOW INDEX FROM ' . $tableSpec ;
  
            $stmt = $this->_db->query($sql);
            $result = $stmt->fetchAll();
            foreach ($result as $rows){
                if ('0' == $rows['Non_unique']){

                  	$this->_uniques[$rows['Key_name']][] = $rows['Column_name'];    
                  	$this->_metadata[$rows['Column_name']]['UNIQUE'] = $rows['Key_name'];    
                }
            }
	      }
        return $this->_uniques;
        
    }
    /**
     * 
     */
    protected function _getComments()
    {
    	if (empty($this->_comments) && $this->_db instanceof Zend_Db_Adapter_Pdo_Mysql){
	    	$cols = $this->_getCols();
	        $this->_comments = array_combine($cols, $cols);
	        $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
        	$sql = 'SHOW FULL FIELDS FROM ' . $tableSpec;
  
            $stmt = $this->_db->query($sql);
            $result = $stmt->fetchAll();
            foreach ($result as $rows){
                if (!empty($rows['Comment'])){
                    $this->_comments[$rows['Field']] = $rows['Comment'];
                    $this->_metadata[$rows['Field']]['COMMENT'] = $rows['Comment'];
                }
                
            }
    	}
        //$this->_comments = array_merge($comments, $this->_comments);
        return $this->_comments; 
    }
    
    public function getUniques($key = null)
    {
    	if (empty($this->_uniques)){
        	$this->_getUniques();
    	}
        if (null === $key){
            return $this->_uniques;
        }
        else{
            return isset($this->_uniques[$key]) ? $this->_uniques[$key] : null;
        }
    }
    
    public function setComments(array $comments)
    {
    	if (empty($this->_comments)){
    		$this->_comments = $this->_getComments();
    	}
        $this->_comments = array_merge($this->_comments, $comments);
        return $this;
    }
    
    public function setComment($col,$comment)
    {
    	if (empty($this->_comments)){
        	$this->_comments = $this->_getComments();
        }
        if (isset($this->_metadata[$col])){
            $this->_comments[$col] = $comment;
        }
        return $this;
    }
    
    public function getComments($ref = false,$joins = array())
    {
    	if (empty($this->_comments)){
        	$this->_comments = $this->_getComments();
        }
        $comments = $this->_comments;
        $joins = (array) $joins;
        if ($ref || !empty($joins)){
            $tables = $this->getParentTable();
            if (!empty($tables)){
                foreach ($tables as $key => $table){
                    if (empty($joins) || in_array($key,$joins)){
                        $parentComments = $table->getComments($ref,$joins);
                        foreach ($parentComments as $pkey => $comment) {
                    	    $comments[$key . '_' . $pkey] = $comment;
                        }
                    }
                    
                }
            }
        }
        return $comments;
    }
    
	public function getTitles($ref = false,$joins = array())
    {
        $cols = $this->_getCols();
        $titles = array();
        foreach ($cols as $col){
        	$t = 'Table-' .$this->_name . '-'.$col;
        	$titles[$col] = Win_Translate::t($t);
        }
        $joins = (array) $joins;
        if ($ref || !empty($joins)){
            $tables = $this->getParentTable();
            if (!empty($tables)){
                foreach ($tables as $key => $table){
                    if (empty($joins) || in_array($key,$joins)){
                        $parentCols = $table->getColNames($ref,$joins);
                        foreach ($parentCols as $pkey => $pCol) {
                    	    $titles[$key . '_' . $pkey] = $pCol;
                        }
                    }
                    
                }
            }
        }
        return $titles;
    }
    
    public function getComment($col)
    {
        $comment = $col;
    	if (empty($this->_comments)){
        	$this->_comments = $this->_getComments();
        }
        if (isset($this->_comments[$col])){
            $comment = $this->_comments[$col];
        }
        elseif(false !== strpos($col, '_')){
            //处理关联表
            $tables = $this->getParentTable();
            if (!empty($tables)){
                foreach ($tables as $key => $table){
                    $pos = strpos($col, $key .'_');
                    if (0 === $pos){
                       $colName = substr($col, strlen($key) + 1);
                       $comment = $table->getComment($colName);
                       if ($comment == $colName) $comment = $col;
                       break; 
                    }
                }
            }
        }
        
        return $comment;
    }
    
	public function getTitle($col)
    {
        $cols = $this->_getCols();
        $title = $col;
        
        if (isset($cols[$col])){
        	$t = 'Table-' .$this->_name . '-'.$col;
            $title = Win_Translate::t($t);
        }
        elseif(false !== strpos($col, '_')){
            //处理关联表
            $tables = $this->getParentTable();
            if (!empty($tables)){
                foreach ($tables as $key => $table){
                    $pos = strpos($col, $key .'_');
                    if (0 === $pos){
                       $colName = substr($col, strlen($key) + 1);
                       $title = $table->Title($colName);
                       if ($title == $colName) $title = $col;
                       break; 
                    }
                }
            }
        }
        if ($title == $col){
        	$t = 'Table-' .$this->_name . '-'.$col;
            $title = Win_Translate::t($t);
        }
        return $title;
    }
    
    public function getPrimary()
    {
    	if (null === $this->_primary){
    		$this->_setupPrimaryKey();
    	}
        return $this->_primary;
    }
    
    public function getPk(){
    	$primary = (array) $this->getPrimary();
        return $primary[(int)$this->_identity];
        
    }
    
    public function getCols()
    {
        return $this->_getCols();
    }
    
    public function findAll($where = null, $order = null, $count = null, $offset = null,$cols = '*', $joins = null)
    {
        $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
        $joins = (array) $joins;
        
        if (empty($cols)){
            $cols = '*';
        }
        
        $cols = (array) $cols;
        
        $asCols = array();
        foreach ($cols as $k=>$col){
            if ('*' == $col){
                $asCols[] = $this->_name . ".*";
            }
            else if ($this->_name. '.*' == $col || in_array(str_replace($this->_name.'.','',$col),$this->_getCols())){
                $asCols[]= $col;
                unset($cols[$k]);
            }
            else if (preg_match('/\(.*\)/', $col)) {
                $asCols[] = new Zend_Db_Expr($col);
                unset($cols[$k]);
            }
        }
        
        //$asCols = array_intersect($this->_cols,$cols);
        
        $select = $this->_db->select()
                        ->from($tableSpec, $asCols);
        try{
            $this->_joinReferenceTable($select,'', $cols, $joins);
        }catch (Zend_Exception $e)
        {
        	Win_Log::err($e->getMessage());
            throw new Win_Db_Exception($e->getMessage());
        }
        if ($where !== null) {
            $this->_whereSelect($select, $where);
        }

        if ($order !== null) {
        	if (is_string($order)){
        		$order = explode(',',$order);
        	}
            $order = (array) $order;
            foreach ($order as $val) {
            	
                /*
                 if (false === strpos($val, '.')){
                     $val = $this->_name .  '.' . $val;
                 }
				*/
                if (false === strpos($val, '.')){
                    $val = preg_replace("/^([A-Z]\w+)_([a-z])/U","\$1.\$2",$val,1);
                    $select->order($val); 
                }else{
                	$select->order($val);
                }
             }
        }
        if ($count !== null || $offset !== null) {
            $select->limit($count, $offset);
        }
        try {
	        $stmt = $this->_db->query($select);
	        $stmt->setFetchMode(Zend_Db::FETCH_ASSOC);
	        $rows = $stmt->fetchAll();
	        $data  = array(
	            'table'    => $this,
	            'data'     => $rows,
	            'readOnly' => false,
	            'rowClass' => $this->_rowClass,
	            'stored'   => true
	        );
        
            @Zend_Loader::loadClass($this->_rowsetClass);
        } catch (Zend_Exception $e) {
            throw new Win_Db_Exception($e->getMessage());
        }
        return new $this->_rowsetClass($data);
    }
    
    public function updateAll(array $data, $where = null)
    {
        $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
        $select = $this->_db->select()
                        ->from($tableSpec);
        try{
            $this->_joinReferenceTable($select);    
        }catch (Zend_Exception $e)
        {
            throw new Win_Db_Exception($e->getMessage());
        }
        
        $set = array();
        foreach ($data as $col => $val) {
            if ($val instanceof Zend_Db_Expr) {
                $val = $val->__toString();
                unset($data[$col]);
            } else {
                $val = '?';
            }
            if (false === strpos($col, '.')){
				$set[] = preg_replace("/^([A-Z]\w+)_([a-z])/U","\$1.\$2",$col,1) . ' = ' . $val;
            }
            else{
                $set[] = $col . ' = ' . $val;
            }
        }
        
        if ($where !== null) {
             $this->_whereSelect($select, $where);
        }
        
        $matches = array();
        preg_match('/^SELECT.+FROM(.+?)( WHERE.+?)$/s', $select->__toString(), $matches);
        $sql = 'UPDATE '
             . $matches[1]
             . ' SET ' . implode(', ', $set)
             . $matches[2];
        $stmt = $this->_db->query($sql,array_values($data));
        $result = $stmt->rowCount();
        return $result;
     }

     
    public function deleteAll($where = null, $rules = null)
    {
        $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
        $select = $this->_db->select()
                        ->from($tableSpec);
        
                        
        if (null === $rules){
            $rules = array($tableSpec);
            $rules = array_merge($rules,$this->getDelRules());
        }
        
        $rules = (array) $rules;        
        $delTables = array();
        foreach ($rules as $table){
            $delTables[] = $table . '.*';
        }
                        
        try{
            $this->_joinReferenceTable($select,'','*',$rules);    
        }catch (Win_Exception $e)
        {
            throw new Win_Db_Exception($e->getMessage());
        }
        
        
        unset($rules);
        if ($where !== null) {
            $this->_whereSelect($select, $where);
        }
        
        
        $sql = 'DELETE '
             . implode(', ', $delTables)
             . strstr($select ,' FROM ');
        $stmt = $this->_db->query($sql);
        $result = $stmt->rowCount();
        return $result;
     }
     
    public function findCount($where = null,$link = false)
    {
        $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
        $select = $this->_db->select()
                        ->from($tableSpec);
        if ($link){
            try{
                $this->_joinReferenceTable($select);    
            }catch (Zend_Exception $e)
            {
                throw new Win_Db_Exception($e->getMessage());
            }
        }
        if ($where !== null) {
            $this->_whereSelect($select, $where);
        }
        
        
        $sql = 'SELECT COUNT(*) '
             . strstr($select ,' FROM ');
        return (int) $this->_db->fetchOne($sql);
    }
        
    protected function _whereSelect(Zend_Db_Select $select, $where)
    {
        $where = (array) $where;
        foreach ($where as $key => $val) {
            if (is_int($key)) {
                /*
                $val = ltrim($val);                 
                if (!preg_match('/^\w+\.\w+/', $val))
                {    
                    $val = $this->_name . '.' . $val;
                } 
				*/                        
                $select->where($val);
            } else {
                /*
                if (false === strpos($key, '.')){
                    $key = $this->_name . '.' . ltrim($key);
                }
				*/
                $select->where($key, $val);
            }
        }
        return $select;
    }
    /*
     *
     */
    protected function __call($method, array $args)
    {
        $matches = array();
        if (preg_match('/^(find|update|delete|count)By(\w+?)(?:And(\w+))*?$/', $method, $matches)) {
            $columnNum = count($matches) - 2;
            $argsNum = count($args);
            $where = null;
            if ($columnNum > $argsNum){
                throw new Win_Db_Exception("Wrong parameter count for method '$method()'");
            }
            for($i = 0; $i < $columnNum; ++$i) {
                $column = $this->_getMatchColumnName($matches[$i + 2]);
                $where[] = $this->_db->quoteInto($this->_name . '.' . $column .' = ? ', $args[$i]);
            }
            
            switch ($matches[1]){
                case 'find':
                    $order = null;
                    $count = null;
                    $offset = null;
                    //order
                    if (isset($args[$i]))
                    {
                        $order = $args[$i];
                    }
                    //count offset
                    if (isset($args[$i + 2]))
                    {
                        $count = (int) $args[$i + 1];
                        $offset = (int) $args[$i + 2];
                    }
                    
                    return $this->findAll($where, $order, $count, $offset);
                    break;
                case 'update':
                    $data = array();
                    $table = null;
                    //data
                    if (isset($args[$i]))
                    {
                        $data = (array) $args[$i];
                    }
                    else{
                        throw new Win_Db_Exception("Data is need for method '$method()'");
                    }
                    //table
                    if (isset($args[$i + 1]))
                    {
                        $table = $args[$i + 1];
                    }
                    
                    return $this->updateAll($data, $where, $table);
                    break;
                case 'delete':
                    $tables = null;
                    if (isset($args[$i]))
                    {
                        $tables = (array) $args[$i];
                    }
                    return $this->deleteAll($where, $tables);
                    break;
                case 'count':
                    return $this->findCount($where);
                    break;
            }
            
            
        }
            
        throw new Win_Db_Exception("Unrecognized method '$method()'");
    }
    
    
    
    public function getDelRules()
    {
        $delRules = array();
        foreach ($this->_getReferenceMapNormalized() as $rule => $map) {
            if (isset($map[self::ON_DELETE])) {
                switch ($map[self::ON_DELETE]) {
                    case self::CASCADE:
                        $delRules[] = $rule;
                        break;
                     default:
                         break;
                }
            }
        }
        
        return $delRules;
    }
    /**
     * 关联查询父表，支持无限关联。可以根据cols和joins设置关联那些表。
     * 
     * 
     */
    protected function _joinReferenceTable(Zend_Db_Select $select, $alise = '',$cols = '*',$joins = null)
    {
        $joins = (array) $joins;
        //if ($cols != '*')
        $cols = (array) $cols;
        foreach ($this->_getReferenceMapNormalized() as $rule => $map) {
            
            $cond = '';
            if ($alise ==''){
                $curAlise = $this->_name;
                $refAlise = $rule;
            }
            else
            {
                $curAlise = $alise;
                $refAlise = $alise . '_' . $rule;
            }
            
            $t = $this->getParentTable($rule);
                        
            $asCols = $t->getAliseCols($refAlise,$cols);
            
            if ((empty($asCols) || $cols ==array('*')) && !empty($joins) && !in_array($rule, $joins) && !in_array($map[self::REF_TABLE_CLASS],$joins)){
                continue;
            }
            for ($i = 0; $i < count($map[self::COLUMNS]); ++$i) {
                $col = $this->_db->foldCase($map[self::COLUMNS][$i]);
                $refCol = $this->_db->foldCase($map[self::REF_COLUMNS][$i]);
                $cond .= ' ' 
                        . $this->_db->quoteIdentifier($curAlise, true) 
                        . '.' 
                        . $this->_db->quoteIdentifier($col, true) 
                        . ' = ' 
                        . $this->_db->quoteIdentifier($refAlise, true)  
                        . '.' 
                        . $this->_db->quoteIdentifier($refCol, true);
            } 
            $select->joinLeft($t->info('name') . ' AS ' . $refAlise, $cond, $asCols);
            $t->_joinReferenceTable($select, $refAlise,$cols,$joins);
             
        }
        return $select;
    }
    
    /**
     * 获得查询字段别名数组
     * 
     */
    public function getAliseCols($asPrefix, $cols = '*')
    {
        $asCols = array();
        $cols = (array) $cols;
        $showAll = false;
        $flipCols = array_flip($cols);
        if (isset($flipCols['*']) || isset($flipCols[$this->_name . ' .*'])  || isset($flipCols[$asPrefix . ' .*'])){
            $showAll = true;
        }
        $thisCols = $this->_getCols();
        foreach ($thisCols as $col)
        {
            if ($showAll){
                $asCols[] = $col . ' AS ' . $asPrefix . '_' . $col;
            }
            else{
                if (isset($flipCols[$asPrefix . '_' . $col])){
                    $asCols[] = $col . ' AS ' . $asPrefix . '_' . $col;
                    unset($cols[$flipCols[$asPrefix . '_' . $col]]);
                } else if (isset($flipCols[$asPrefix . '.' . $col])){
                    $asCols[] = $col . ' AS ' . $asPrefix . '_' . $col;
                    unset($cols[$flipCols[$asPrefix . '.' . $col]]);
                } else if (isset($flipCols[$this->_name . '.' . $col])){
                    $asCols[] = $col . ' AS ' . $asPrefix . '_' . $col;
                    unset($cols[$flipCols[$this->_name . '.' . $col]]);
                }
            }
        }
        return $asCols;
    }
    
    
    public function getPrefixCols($prefix)
    {
        $pfCols = array();
        $cols = $this->_getCols();
        foreach ($cols as $col)
        {
            $pfCols[] = $prefix . '_' . $col;
        }
        return $pfCols;
    }
    
    /**
     * 
     */
    protected function _getMatchColumnName($name)
    {
       $cols = $this->_getCols();
       foreach ($cols as $columnName)
       {
           if (strtolower($name) == strtolower($columnName))
               return $columnName;
       }
       throw new Win_Db_Exception('Specified column ' . $name . ' is not in the table ' . $this->_name);
    }
    
    /**
     * 
     */
    public function getReferenceMap($ruleKey = null)
    {
        $thisClass = get_class($this);
        $refMap = $this->_getReferenceMapNormalized();
        if ($ruleKey !== null) {
            if (!isset($refMap[$ruleKey])) {
                throw new Win_Db_Exception("No reference rule \"$ruleKey\" at table $thisClass ");
            }
            return $refMap[$ruleKey];
        }
        return $refMap;
    }

    /**
     * 
     */
    public function getParentTable($ruleKey = null)
    {
        $parentTables = array();
        $maps = $this->getReferenceMap($ruleKey);
        
        if ($ruleKey !== null){
            $maps = array($ruleKey => $maps);
        }
        
        $db = $this->getAdapter();            
        foreach ($maps as $key => $map)
        {
            if (isset($map[self::REF_TABLE]) && $map[self::REF_TABLE] instanceof Win_Db_Table){
               $parentTables[$key] = $map[self::REF_TABLE];
            }
            else{
                $tableClass = $map[self::REF_TABLE_CLASS];
                try {
                    @Zend_Loader::loadClass($tableClass);
                } catch (Zend_Exception $e) {
                    throw new Win_Db_Exception($e->getMessage());
                }              
                $parentTables[$key] = new $tableClass(array(self::ADAPTER => $db));
                $this->_referenceMap[$key][self::REF_TABLE] = $parentTables[$key];
            }
        }
        if ($ruleKey !== null){
            return $parentTables[$ruleKey];
        }
        else{
            return $parentTables;   
        }
    }
    

	public function encode($data)
    {
    	return Win_Common::encrypt($data,md5('Table' . $this->_name));
    }
    
    public function decode($data)
    {
		return Win_Common::decrypt($data,md5('Table' . $this->_name));
    }
    
    //if all primary key is not null and not '',than update else insert
    public function save(array $data)
    {
        $primary = (array) $this->getPrimary();
        $cols = $this->_getCols();
        $pkData = array_intersect_key($data, array_flip($primary));
        $where = array();
        $flipCols = array_flip($cols);
        $data = array_intersect_key($data, $flipCols);
        foreach ($primary as $key)
        {
            if (!isset($pkData[$key]) || '' === $pkData[$key])
            {
                if (isset($flipCols['created'])){
                    $data['created'] = time();
                }
                return $this->insert($data);
            }
            $where[] = $this->_db->quoteInto($key . ' = ?', $pkData[$key]);
        }
        if (isset($flipCols['updated'])){
            $data['updated'] = time();
        }
        return $this->update($data, $where);
    }
    
    
    public function getMap($id = 'id', $val = 'name', $query = null,$order = null)
    {
        $rowset = $this->findAll($query,$order);
        $map = array();
         foreach ($rowset as $row) {
            $map[$row->$id] = $row->$val;
        }
        return $map;
    }
    
    public function isExist($where, $id = null)
    {
        $where = (array) $where;
        if (null !== $id || '' !== $id){
            $where[] = $this->_db->quoteInto('id != ?',$id);
        }            
        return (null !== $this->fetchRow($where));
    }
	
    public function ajaxQuery($request, $where = null,$cols = '*',$joins = null)
    { 
        $rp =  $request->getPost('rp',10);
        $page =  $request->getPost('page',1);
        $qtype =  $request->getPost('qtype','');               //like搜索关键字
        $sortname =  $request->getPost('sortname','');
        $sortorder =  $request->getPost('sortorder','');
        $query =  $request->getPost('query','');               //条件where
        $qvalue =  $request->getPost('qvalue','');
        $delids =  $request->getPost('delids','');             //id
        $queryType =  $request->getPost('queryType','search');

        $where = (array) $where;
        if (empty($query))
            $query = null;
        else{
            //$query = trim(Win_Common::decrypt($query,'grid'));
            $where[] = $query;
        }
        $order = null;                 
        if (! empty($sortname)){
            //$sortname = preg_replace("/^([A-Z]\w+)_([a-z])/U","\$1.\$2",$sortname,1);
            $order .= $sortname;          
        }
        if (!empty($sortorder) && !empty($order)){
            $order .= ' ' . $sortorder;
        }
        
        if ($rp =='ALL'){
            $page = 1;
            $offset = null;
            $count = null;
        } else {
            $count = (int) $rp;
            $offset = (int)$rp*($page -1);
        }
                  
        $db = $this->getAdapter();
        try{
            if ('delete' == $queryType && ! empty($delids))
            {
                $dsql = $db->quoteInto($this->_name . '.id in (?)',explode(',',$delids));
                $this->deleteAll($dsql);
            }
            
            if(!empty($qvalue) && !empty($qtype))
            {
                $qtype = preg_replace("/^([A-Z]\w+)_([a-z])/U","\$1.\$2",$qtype,1);
                $where[] = $db->quoteInto($qtype . ' like ?','%' . $qvalue . '%');
            }
            $rows = $this->findAll($where,$order, $count,$offset,$cols, $joins);
            $total = $this->findCount($where,true);
            $arrayJson = array();
            $arrayJson['page'] = $page;
            $arrayJson['total'] = $total;
          
            foreach ($rows as $row)
            {              
                $arrayJson['rows'][$row->id] = array_diff($row->toArray(), array(0=>null));
            }
            if (!isset($arrayJson['rows'])){
             $arrayJson['rows']= array();
             $arrayJson['w'] = $where;
            }
        }
        catch (Exception $e){
            return array('page'=>1,'total'=>0,'rows'=>array(),'debug'=>$e->getMessage(),'w'=>$where);
        }
        return $arrayJson;
    }
    /**
	 *  导入一条数据
	 *  @param array $row 当前要导入的一条数据
	 *  @param array $cols 导入的字段
	 *  @param array $defs 字段默认值
	 *  @param bool $isUpdate 更新或者新增
	 */
    public function import(array $row,array $cols,array $defs,$isUpdate = false)
    {
        $data = array();
        $where = array();
        foreach ( $cols as $colName=>$num ) {
			//判断该字段是否有值,如果没有值赋值为“默认值”$defs或者null
            if ($num >=0 && isset($row[$num])){
				//去除双引号
            	$row[$num] = str_replace("\"","",$row[$num]);
				if ( $lang = Win_Translate::getInstance()->getLocale() ) {
				    switch ( $lang ) {
        	            case 'ja': $row[$num] = iconv('Shift_JIS', 'UTF-8',$row[$num]); break;
        	            case 'zh': $row[$num] = iconv('gb2312', 'UTF-8',$row[$num]); break;
					}
				} else {
				    $row[$num] = iconv('gb2312','UTF-8',$row[$num]);
				}
                $data[$colName] = $row[$num];
            } else {
                $data[$colName] = isset($defs[$colName]) ? $defs[$colName] : null;
            }
            /*if ( !empty($this->_metadata[$colName]['UNIQUE']) ) {
                $where[] = $this->_db->quoteInto($colName . '=?',$data[$colName]);
            }*/
        }
        /*if ( !empty($where) ) {
            $count  = $this->findCount($where);
        }*/
        if ( $isUpdate ) {
            if ( $count == 1 ) {
                $ret = (int) $this->update($data,$where);//返回更新记录数
                if ($ret == 0) {
                    return 'hasTheSame';
                } else {
                    return 1;
                }
            } else {
                //$where = array('id' => $data['id']);
                return (int) $this->save($data);
            }
        } else {
            if ($count > 0 ){
                return 'isExist';
            }
            else{
            	//unset($data['id']);
                //return (int) $this->save($data);
				//如果选择新增记录（即删除原表），插入数据
				return (int) $this->insert($data);
            }    
        }
    }
}
